home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Tech Arsenal 1
/
Tech Arsenal (Arsenal Computer).ISO
/
tek-01
/
ue312src.zip
/
NT.C
< prev
next >
Wrap
C/C++ Source or Header
|
1993-01-05
|
18KB
|
571 lines
/* NT.C: Operating specific I/O and Spawning functions
* for the Window NT operating system (console mode)
* for MicroEMACS 3.12
* (C)Copyright 1993 by Daniel M. Lawrence
* Windows NT version by Walter Warniaha
*
* Note: don't try to compile this on non Windows NT systems.... The header
* files won't exist.
*
* Modifications needed: check that we don't construct command lines and
* temporary filenames which are too large for their buffers.
*
*/
#undef PASCAL
#undef NEAR
#undef HIBYTE
#include "estruct.h"
#include "eproto.h"
#if WINNT
#include "elang.h"
#include "edef.h"
#include <process.h>
#include <io.h>
/*
* Create a subjob with a copy of the command intrepreter in it. When the
* command interpreter exits, mark the screen as garbage so that you do a full
* repaint. Bound to "^X C". The message at the start in VMS puts out a newline.
* Under some (unknown) condition, you don't get one free when DCL starts up.
*/
PASCAL NEAR spawncli(f, n)
{
/* don't allow this command if restricted */
if (restflag)
return(resterr());
movecursor(term.t_nrow, 0); /* Seek to last line. */
TTflush();
TTkclose();
shell();
TTkopen();
sgarbf = TRUE;
return(TRUE);
}
/*
* Run a one-liner in a subjob. When the command returns, wait for a single
* character to be typed, then mark the screen as garbage so a full repaint is
* done. Bound to "C-X !".
*/
PASCAL NEAR spawn(f, n)
{
register int s;
char line[NLINE];
/* don't allow this command if restricted */
if (restflag)
return(resterr());
if ((s=mlreply("!", line, NLINE)) != TRUE)
return(s);
movecursor(term.t_nrow - 1, 0);
TTkclose();
system(line);
TTkopen();
/* if we are interactive, pause here */
if (clexec == FALSE) {
puts(TEXT6);
/* "\r\n\n[End]" */
tgetc();
}
sgarbf = TRUE;
return (TRUE);
}
/*
* Run an external program with arguments. When it returns, wait for a single
* character to be typed, then mark the screen as garbage so a full repaint is
* done. Bound to "C-X $".
*/
PASCAL NEAR execprg(f, n)
{
register int s;
char line[NLINE];
/* don't allow this command if restricted */
if (restflag)
return(resterr());
if ((s=mlreply("$", line, NLINE)) != TRUE)
return(s);
movecursor(term.t_nrow - 1, 0);
TTkclose();
execprog(line);
TTkopen();
/* if we are interactive, pause here */
if (clexec == FALSE) {
puts(TEXT6);
/* "\r\n\n[End]" */
tgetc();
}
sgarbf = TRUE;
return (TRUE);
}
/*
* Pipe a one line command into a window
* Bound to ^X @
* We use a unique temporary file name so that multiple instances of
* MicroEMACS don't try to use the same file.
*/
PASCAL NEAR pipecmd(f, n)
{
register WINDOW *wp; /* pointer to new window */
register BUFFER *bp; /* pointer to buffer to zot */
register char *tmp; /* ptr to TMP DOS environment variable */
char line[NLINE]; /* command line send to shell */
static char bname[] = "command";
static char filnam[NSTRING];
char *getenv();
/* don't allow this command if restricted */
if (restflag)
return(resterr());
/* get rid of the command output buffer if it exists */
if ((bp=bfind(bname, FALSE, 0)) != FALSE) {
/* try to make sure we are off screen */
wp = wheadp;
while (wp != NULL) {
if (wp->w_bufp == bp) {
onlywind(FALSE, 1);
break;
}
wp = wp->w_wndp;
}
/* get rid of the existing command buffer */
if (zotbuf(bp) != TRUE)
return(FALSE);
}
/* get the command to pipe in */
if (mlreply("@", line, NLINE) != TRUE)
return(FALSE);
/* Call mktemp() to get a unique filename in the tmp directory. */
if ((tmp = getenv("TMP")) == NULL)
filnam[0] = 0;
else {
strcpy(filnam, tmp);
if (filnam[strlen(filnam) - 1] != '\\')
strcat(filnam, "\\");
}
strcat(filnam,"eXXXXXX");
mktemp(filnam);
/* redirect the command output to the output file */
strcat(line, " >>");
strcat(line, filnam);
movecursor(term.t_nrow - 1, 0);
/* execute the command */
TTkclose();
system(line);
TTkopen();
sgarbf = TRUE;
/* did the output file get generated? */
if (access( filnam, 0) != 0)
return(FALSE);
/* split the current window to make room for the command output */
if (splitwind(FALSE, 1) == FALSE)
return(FALSE);
/* and read the stuff in */
if (getfile(filnam, FALSE) == FALSE)
return(FALSE);
/* rename the buffer */
strcpy( curwp->w_bufp->b_bname, "command");
/* make this window in VIEW mode, update all mode lines */
curwp->w_bufp->b_mode |= MDVIEW;
wp = wheadp;
while (wp != NULL) {
wp->w_flag |= WFMODE;
wp = wp->w_wndp;
}
/* and get rid of the temporary file */
unlink(filnam);
return(TRUE);
}
/*
* filter a buffer through an external DOS program
* Bound to ^X #
* We use unique temporary file names so that multiple instances of
* MicroEMACS don't try to use the same file.
*/
PASCAL NEAR filter(f, n)
{
register int s; /* return status from CLI */
register BUFFER *bp; /* pointer to buffer to zot */
char line[NLINE]; /* command line send to shell */
char tmpnam[NFILEN]; /* place to store real file name */
char *tmp; /* ptr to TMP DOS environment variable */
static char filnam1[NSTRING];
static char filnam2[NSTRING];
/* don't allow this command if restricted */
if (restflag)
return(resterr());
if (curbp->b_mode&MDVIEW) /* don't allow this command if */
return(rdonly()); /* we are in read only mode */
/* get the filter name and its args */
if ((s=mlreply("#", line, NLINE)) != TRUE)
return(s);
/* Call mktemp() to get unique filenames in the tmp directory. */
if ((tmp = getenv("TMP")) == NULL)
filnam1[0] = filnam2[0] = 0;
else {
strcpy(filnam1, tmp);
strcpy(filnam2, tmp);
if (filnam1[strlen(filnam1) - 1] != '\\') {
strcat(filnam1, "\\");
strcat(filnam2, "\\");
}
}
strcat(filnam1,"eXXXXXX");
strcat(filnam2,"eXXXXXX");
mktemp(filnam1);
/* setup the proper file names */
bp = curbp;
strcpy(tmpnam, bp->b_fname); /* save the original name */
strcpy(bp->b_fname, filnam1); /* set it to our new one */
/* write it out, checking for errors */
if (writeout(filnam1, "w") != TRUE) {
mlwrite(TEXT2);
/* "[Cannot write filter file]" */
strcpy(bp->b_fname, tmpnam);
return(FALSE);
}
mktemp(filnam2);
strcat(line, " <"); /* construct the command line */
strcat(line, filnam1);
strcat(line, " >");
strcat(line, filnam2);
movecursor(term.t_nrow - 1, 0);
TTkclose();
system(line);
TTkopen();
sgarbf = TRUE;
s = TRUE;
/* on failure, escape gracefully */
if (s != TRUE || (readin(filnam2,FALSE) == FALSE)) {
mlwrite(TEXT3);
/* "[Execution failed]" */
strcpy(bp->b_fname, tmpnam);
unlink(filnam1);
unlink(filnam2);
return(s);
}
/* reset file name */
strcpy(bp->b_fname, tmpnam); /* restore name */
bp->b_flag |= BFCHG; /* flag it as changed */
/* and get rid of the temporary file */
unlink(filnam1);
unlink(filnam2);
return(TRUE);
}
/* SHELL: Bring up a shell. */
shell(void)
{
char *shell; /* Name of system command processor */
/* get name of system shell */
if ((shell = getenv("COMSPEC")) == NULL) {
return(FALSE); /* No shell located */
}
return (spawnlp(P_WAIT, shell, NULL));
}
execprog( char *cmd)
{
char args[NSTRING]; /* args passed to program */
char *sp;
char failName[NFILEN];
char prog[NSTRING]; /* name of program */
USHORT i;
/*
* Parse the command name from the command line and copy it
* into the prog and args arrays.
*/
i = 0;
while (cmd[i] && (cmd[i] != ' ') && (cmd[i] != '\t')) {
prog[i] = args[i] = cmd[i];
i++;
}
prog[i] = args[i] = 0; /* terminate with a null */
/* skip whitespace and copy the args */
while (cmd[i] && ((cmd[i] == ' ') || (cmd[i] == '\t')))
i++;
while (cmd[i]) {
args[i] = cmd[i];
i++;
}
args[i] = args[i + 1] = 0; /* terminate with 2 nulls */
/* look up the program on the path, trying various extentions */
if ((sp = flook(prog, TRUE)) == NULL)
if ((sp = flook(strcat(prog, ".exe"), TRUE)) == NULL) {
return(FALSE);
}
strcpy(prog, sp);
/*
* Execute the program synchronously. We wait for child
* to return.
*/
return (0 == spawnl(P_WAIT, prog, args, NULL));
}
/* FILE Directory routines */
struct _finddata_t pBuf; /* buffer to hold file information */
long lDir; /* directory handle */
int num_found; /* number of directory entries found/to find */
char path[NFILEN]; /* path of file to find */
char rbuf[NFILEN]; /* return file buffer */
/* do a wild card directory search (for file name completion) */
char *PASCAL NEAR getffile(fspec)
char *fspec; /* pattern to match */
{
register int index; /* index into various strings */
register int point; /* index into other strings */
register int extflag; /* does the file have an extention? */
char fname[NFILEN]; /* file/path for DOS call */
/* first parse the file path off the file spec */
strcpy(path, fspec);
index = strlen(path) - 1;
while (index >= 0 && (path[index] != '/' &&
path[index] != '\\' && path[index] != ':'))
--index;
path[index+1] = 0;
/* check for an extension */
point = strlen(fspec) - 1;
extflag = FALSE;
while (point > index) {
if (fspec[point] == '.') {
extflag = TRUE;
break;
}
point--;
}
/* construct the composite wild card spec */
strcpy(fname, path);
strcat(fname, &fspec[index+1]);
strcat(fname, "*");
if (extflag == FALSE)
strcat(fname, ".*");
/* and call for the first file */
num_found = 1;
if ((lDir = _findfirst(fname, &pBuf)) == NULL)
return(NULL);
/* return the first file name! */
strcpy(rbuf, path);
strcat(rbuf, pBuf.name);
mklower(rbuf);
if (pBuf.attrib == _A_SUBDIR)
strcat(rbuf, DIRSEPSTR);
return(rbuf);
}
char *PASCAL NEAR getnfile()
{
register int index; /* index into various strings */
register int point; /* index into other strings */
register int extflag; /* does the file have an extention? */
char fname[NFILEN]; /* file/path for DOS call */
/* and call for the next file */
if (_findnext(lDir, &pBuf) != 0)
return(NULL);
/* return the first file name! */
strcpy(rbuf, path);
strcat(rbuf, pBuf.name);
mklower(rbuf);
if (pBuf.attrib == _A_SUBDIR)
strcat(rbuf, DIRSEPSTR);
return(rbuf);
}
/* return a system dependant string with the current time */
char *PASCAL NEAR timeset()
{
register char *sp; /* temp string pointer */
char buf[16]; /* time data buffer */
extern char *ctime();
time(buf);
sp = ctime(buf);
sp[strlen(sp)-1] = 0;
return(sp);
}
#if OBSOLETE
/* extcode: resolve MSDOS extended character codes
encoding the proper sequences into emacs
printable character specifications
*/
int extcode(
unsigned c /* byte following a zero extended char byte */
)
{
/* function keys 1 through 9 */
if (c >= 59 && c < 68)
return(SPEC | c - 58 + '0');
/* function key 10 */
if (c == 68)
return(SPEC | '0');
/* shifted function keys */
if (c >= 84 && c < 93)
return(SPEC | SHFT | c - 83 + '0');
if (c == 93)
return(SPEC | SHFT | '0');
/* control function keys */
if (c >= 94 && c < 103)
return(SPEC | CTRL | c - 93 + '0');
if (c == 103)
return(SPEC | CTRL | '0');
/* ALTed function keys */
if (c >= 104 && c < 113)
return(SPEC | ALTD | c - 103 + '0');
if (c == 113)
return(SPEC | ALTD | '0');
/* ALTed number keys */
if (c >= 120 && c < 129)
return(ALTD | c - 119 + '0');
if (c == 130)
return(ALTD | '0');
/* some others as well */
switch (c) {
case 3: return(0); /* null */
case 15: return(SHFT | CTRL | 'I'); /* backtab */
case 16: return(ALTD | 'Q');
case 17: return(ALTD | 'W');
case 18: return(ALTD | 'E');
case 19: return(ALTD | 'R');
case 20: return(ALTD | 'T');
case 21: return(ALTD | 'Y');
case 22: return(ALTD | 'U');
case 23: return(ALTD | 'I');
case 24: return(ALTD | 'O');
case 25: return(ALTD | 'P');
case 30: return(ALTD | 'A');
case 31: return(ALTD | 'S');
case 32: return(ALTD | 'D');
case 33: return(ALTD | 'F');
case 34: return(ALTD | 'G');
case 35: return(ALTD | 'H');
case 36: return(ALTD | 'J');
case 37: return(ALTD | 'K');
case 38: return(ALTD | 'L');
case 44: return(ALTD | 'Z');
case 45: return(ALTD | 'X');
case 46: return(ALTD | 'C');
case 47: return(ALTD | 'V');
case 48: return(ALTD | 'B');
case 49: return(ALTD | 'N');
case 50: return(ALTD | 'M');
case 71: return(SPEC | '<'); /* HOME */
case 72: return(SPEC | 'P'); /* cursor up */
case 73: return(SPEC | 'Z'); /* page up */
case 75: return(SPEC | 'B'); /* cursor left */
case 77: return(SPEC | 'F'); /* cursor right */
case 79: return(SPEC | '>'); /* end */
case 80: return(SPEC | 'N'); /* cursor down */
case 81: return(SPEC | 'V'); /* page down */
case 82: return(SPEC | 'C'); /* insert */
case 83: return(SPEC | 'D'); /* delete */
case 115: return(SPEC | CTRL | 'B'); /* control left */
case 116: return(SPEC | CTRL | 'F'); /* control right */
case 117: return(SPEC | CTRL | '>'); /* control END */
case 118: return(SPEC | CTRL | 'V'); /* control page down */
case 119: return(SPEC | CTRL | '<'); /* control HOME */
case 132: return(SPEC | CTRL | 'Z'); /* control page up */
}
return(ALTD | c);
}
#endif /* obsolete */
#endif
#undef va_start
#undef va_end
#include <varargs.h>
int dprintf(va_alist, ...)
va_dcl
{
va_list arg_ptr;
char buffer[200];
char *fmt;
va_start(arg_ptr);
fmt = va_arg(arg_ptr, char *);
vsprintf(buffer, fmt, arg_ptr);
SetConsoleTitle(buffer);
}